﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using SilverAmp.Shared;

namespace SilverAmp
{
    [Export(typeof(IMainModel))]
    public class MainModel : IMainModel
    {
        public event EventHandler MusicLoaded;

        public ObservableCollection<ITrackInfo> AvailableSongs { get; private set; }
        public ITrackInfo SelectedSong { get; set; }
        public ITrackInfo CurrentlyPlayingSong { get; set; }


        private ISongInformationProvider _songInformationProvider;

        private BackgroundWorker bw = new BackgroundWorker();

        public MainModel()
        {
            context = SynchronizationContext.Current;
            AvailableSongs = new ObservableCollection<ITrackInfo>();

            bw.DoWork += delegate { LoadMusic(); };
            bw.RunWorkerAsync();
            MusicLoaded += OnMusicLoaded;
        }





        private SynchronizationContext context;
        private void OnMusicLoaded(object sender, EventArgs e)
        {
           // context.Post(delegate { LoadID3SongInformation(); }, null);

        }


        public void LoadID3SongInformation()
        {
            ISongCollectionInfoProvider songCollectionInfoProvider =
                new SongCollectionInfoProvider(AvailableSongs, new ID3SongInformationProvider());

            songCollectionInfoProvider.UpdateSongs();
        }

        /// <summary>
        /// Loads the music.
        /// </summary>
        private void LoadMusic()
        {
            if (Application.Current.HasElevatedPermissions)
            {                               
               
                string path = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
                DirectoryInfo directoryInfo = new DirectoryInfo(path);

                foreach (FileInfo fileInfo in directoryInfo.EnumerateFiles("*.mp3", 
                    SearchOption.AllDirectories))
                {
                    Deployment.Current.Dispatcher.BeginInvoke(
                            new AddSong(AddSongToPlaylist),
                            new TrackInfo { Artist = fileInfo.Name, Fileinfo = fileInfo }
                        );
                }

                InvokeMusicLoaded();
            }
        }

        private delegate void AddSong(TrackInfo trackInfo);
        private void AddSongToPlaylist(TrackInfo trackInfo)
        {
            AvailableSongs.Add(trackInfo);
        }

        public void InvokeMusicLoaded()
        {
            EventHandler handler = MusicLoaded;
            if (handler != null) handler(this, new EventArgs());
        }

        public bool FileInPlaylist(FileInfo fileInfo)
        {
            return SelectSong(fileInfo) != null;
        }

        public void AddFileToPlaylist(FileInfo fileInfo)
        {
            var ID3SongInfo = new ID3SongInformationProvider();            
            AvailableSongs.Add(ID3SongInfo.GetTrackInfo(fileInfo));
        }


        public ITrackInfo SelectSong(FileInfo fileInfo)
        {
            return AvailableSongs.FirstOrDefault(x => x.Fileinfo.Name == fileInfo.Name);
        }
    }
}